package ruc.MongoDB.write;

import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
import ruc.Consts.constant;
import ruc.utils.IOUtils;
import ruc.MongoDB.MongoDB_Common;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

public class MongoDB_MutiTableWrite {
    private int port;
    private String IP, dbName;

    public MongoDB_MutiTableWrite(String IP, int port, String dbName) {
        this.IP = IP;
        this.port = port;
        this.dbName = dbName;
    }

    private void insert(String[] values, int[] tableNum) throws InterruptedException {
        int idx = 0;
        MongoDatabase mongoDB = MongoDB_Common.GetMongoDB(IP, port, dbName);
        int[] cnt = new int[tableNum.length];
        while(idx < values.length) {
            for(int i = 0; i < tableNum.length; i++) {
                long st_Time = System.nanoTime();
                CountDownLatch countDownLatch = new CountDownLatch(tableNum[i]);
                boolean status = false;
                for(int j = 0; j < tableNum[i]; j++) {
                    if (idx == values.length) {
                        System.out.printf("[TSBench-D] [MongoDB_MultiTableWrite] >>>>>>>> index out of bounds, the length of array:%d >>>>>>>>>>>> \n", values.length);
                        status = true;
                        break;
                    }
                    String[] val = values[idx++].split(constant.Delimiter);
                    MongoCollection<Document> collection = mongoDB.getCollection(constant.MultiTableWrite_tbName + j); // get collection equals create collection
                    Document document = new Document().append("ts",val[0]).append("userInfo", val[1]).append("server", val[2]).append("hostname", val[3])
                            .append("cpu_usage", val[4]).append("memory_usage", val[5]).append("disk_usage", val[6]);
                    // asynchronous insert
                    new Thread(()->{
                        collection.insertOne(document);
                        countDownLatch.countDown(); //countdown
                    }).start();
                }

                if(status) { // stop countdown
                    break;
                }
                countDownLatch.await();
                long ed_Time = System.nanoTime();
                cnt[i] += (ed_Time - st_Time) / constant.Ns2Ms;
            }
        }

        for(int i = 0; i < cnt.length; i++) {
            System.out.printf("[TSBenchD] [MongoDB_MultiTableWrite] >>>>> tableNum：%d, costTime：%d ms >>>>> \n", tableNum[i], cnt[i]);
            IOUtils.WriteData(constant.GetWriteFilePath("MongoDB", "MultiTableWrite"),
                    new String[]{String.valueOf(tableNum[i]), String.valueOf(cnt[i])});
        }
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        MongoDB_MutiTableWrite db = new MongoDB_MutiTableWrite(constant.IP, constant.MongoDB_port, constant.dbName);
        db.insert(IOUtils.GetData(), constant.MutiTable_TableNum);
    }
}
